# -*- coding: utf-8 -*-

"""
注意，此文件未经允许不得商用

此文件乃是修改自 伶伦转换器 的 io.py https://gitee.com/TriM-Organization/Linglun-Converter/blob/master/utils/io.py
伶伦转换器 代码仓库地址为：
https://gitee.com/TriM-Organization/Linglun-Converter

本程序依照 Apache2.0 协议标明其作者，源协议文件位于 `https://gitee.com/TriM-Organization/Linglun-Converter/blob/master/LICENSE.md`
引用协议：

   版权所有 © 2023 睿乐组织 诸葛亮与八卦阵 & 金羿
   Copyright © 2023 TriM-Organization 诸葛亮与八卦阵("bgArray") & 金羿("Eilles Wan")

   Licensed under the Apache License, Version 2.0 (the "License");
   you may not use this file except in compliance with the License.
   You may obtain a copy of the License at

       http://www.apache.org/licenses/LICENSE-2.0

   Unless required by applicable law or agreed to in writing, software
   distributed under the License is distributed on an "AS IS" BASIS,
   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   See the License for the specific language governing permissions and
   limitations under the License.

继承协议：

    版权所有 © 2023 睿乐组织 金羿("Eilles Wan") & 所有 芷词 开发者
    Copyright © 2023 TriM-Organization EillesWan(W-YI_DoctorYI@outlook.com) and all the developers of LyricAngelica

    Licensed under the Apache License, Version 2.0 (the "License");
    you may not use this file except in compliance with the License.
    You may obtain a copy of the License at

        http://www.apache.org/licenses/LICENSE-2.0

    Unless required by applicable law or agreed to in writing, software
    distributed under the License is distributed on an "AS IS" BASIS,
    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    See the License for the specific language governing permissions and
    limitations under the License.
"""


import urllib.error
import urllib.request
from typing import Any, Callable, Literal, Optional, TextIO, Tuple

import TrimLog
from TrimLog import Console, object_constants

is_logging: bool = True

MainConsole = Console()
osc = object_constants.ObjectStateConstant()
logger = TrimLog.Logger(
    is_logging=is_logging,
    printing=not osc.isRelease,
    in_suffix=".lya",
)


try:
    myWords = (
        urllib.request.urlopen(
            "https://gitee.com/TriM-Organization/LinglunStudio/raw/master/resources/myWords.txt"
        )
        .read()
        .decode("utf-8")
        .strip("\n")
        .split("\n")
    )
except (ConnectionError, urllib.error.HTTPError) as E:
    logger.warning(f"读取言·论信息发生 互联网连接 错误：\n{E}")
    myWords = ["以梦想为驱使 创造属于自己的未来"]
# noinspection PyBroadException
except BaseException as E:
    logger.warning(f"读取言·论信息发生 未知 错误：\n{E}")
    myWords = ["灵光焕发 深艺献心"]


JustifyMethod = Literal["default", "left", "center", "right", "full"]
OverflowMethod = Literal["fold", "crop", "ellipsis", "ignore"]


# 高级的打印函数
def prt(
    *objects: Any,
    sep: str = " ",
    end: str = "\n",
    justify: Optional[JustifyMethod] = None,
    overflow: Optional[OverflowMethod] = None,
    no_wrap: Optional[bool] = None,
    emoji: Optional[bool] = None,
    markup: Optional[bool] = None,
    highlight: Optional[bool] = None,
    width: Optional[int] = None,
    height: Optional[int] = None,
    crop: bool = True,
    soft_wrap: Optional[bool] = None,
    new_line_start: bool = False,
) -> None:
    """打印到控制台。

    Args:
        objects (位置性的args): 要记录到终端的对象。
        sep (str, 可选): 要在打印数据之间写入的字符串。默认为""。
        end (str, optio可选nal): 在打印数据结束时写入的字符串。默认值为"\\\\n"。
        justify (str, 可选): 校正位置，可为"default", "left", "right", "center" 或 "full". 默认为`None`。
        overflow (str, 可选): 控制溢出："ignore"忽略, "crop"裁剪, "fold"折叠, "ellipsis"省略号。默认为`None`。
        no_wrap (Optional[bool], 可选): 禁用文字包装。默认为`None`。
        emoji (Optional[bool], 可选): 启用表情符号代码，或使用控制台默认的`None`。默认为`None`。
        markup (Optional[bool], 可选): 启用标记，或`None`使用控制台默认值。默认为`None`。
        highlight (Optional[bool], 可选): 启用自动高亮，或`None`使用控制台默认值。默认为`None`。
        width (Optional[int], 可选): 输出的宽度，或`None`自动检测。默认为`None`。
        height
        crop (Optional[bool], 可选): 裁剪输出到终端的宽度。默认为`True`。
        soft_wrap (bool, 可选): 启用软包装模式，禁止文字包装和裁剪，或`None``用于 控制台默认值。默认为`None`。
        new_line_start (bool, False): 如果输出包含多行，在开始时插入一个新行。默认值为`False`。
    """
    MainConsole.print(
        *objects,
        sep=sep,
        end=end,
        style="#F0F2F4 on #121110",
        justify=justify,
        overflow=overflow,
        no_wrap=no_wrap,
        emoji=emoji,
        markup=markup,
        highlight=highlight,
        width=width,
        height=height,
        crop=crop,
        soft_wrap=soft_wrap,
        new_line_start=new_line_start,
    )


# 高级的输入函数
def ipt(
    *objects: Any,
    sep: str = " ",
    justify: Optional[JustifyMethod] = None,
    overflow: Optional[OverflowMethod] = None,
    no_wrap: Optional[bool] = None,
    emoji: Optional[bool] = None,
    markup: Optional[bool] = None,
    highlight: Optional[bool] = None,
    width: Optional[int] = None,
    height: Optional[int] = None,
    crop: bool = True,
    soft_wrap: Optional[bool] = None,
    new_line_start: bool = False,
    password: bool = False,
    stream: Optional[TextIO] = None,
) -> str:
    """显示一个提示并等待用户的输入。

    它的工作方式与Python内建的 :func:`input` 函数相同，如果Python内建的 :mod:`readline` 模块先前已经加载，则提供详细的行编辑和历史功能。

    Args:
        objects (位置性的args): 要记录到终端的对象。
        sep (str, 可选): 要在打印数据之间写入的字符串。默认为""。
        justify (str, 可选): 校正位置，可为"default", "left", "right", "center" 或 "full". 默认为`None`。
        overflow (str, 可选): 控制溢出："ignore"忽略, "crop"裁剪, "fold"折叠, "ellipsis"省略号。默认为`None`。
        no_wrap (Optional[bool], 可选): 禁用文字包装。默认为`None`。
        emoji (Optional[bool], 可选): 启用表情符号代码，或使用控制台默认的`None`。默认为`None`。
        markup (Optional[bool], 可选): 启用标记，或`None`使用控制台默认值。默认为`None`。
        highlight (Optional[bool], 可选): 启用自动高亮，或`None`使用控制台默认值。默认为`None`。
        width (Optional[int], 可选): 输出的宽度，或`None`自动检测。默认为`None`。
        crop (Optional[bool], 可选): 裁剪输出到终端的宽度。默认为`True`。
        height
        soft_wrap (bool, 可选): 启用软包装模式，禁止文字包装和裁剪，或`None``用于 控制台默认值。默认为`None`。
        new_line_start (bool, False): 如果输出包含多行，在开始时插入一个新行。默认值为`False`。
        password (bool, 可选): 隐藏已经输入的文案，默认值为`False`。
        stream (TextIO, 可选): 可选从文件中读取（而非控制台），默认为 `None`。

    Returns:
        str: 从stdin读取的字符串
    """
    MainConsole.print(
        *objects,
        sep=sep,
        end="",
        style="#F0F2F4 on #121110",
        justify=justify,
        overflow=overflow,
        no_wrap=no_wrap,
        emoji=emoji,
        markup=markup,
        highlight=highlight,
        width=width,
        height=height,
        crop=crop,
        soft_wrap=soft_wrap,
        new_line_start=new_line_start,
    )

    return MainConsole.input(password=password, stream=stream)


def format_ipt(
    notice: str,
    fun: Callable,
    err_note: str = "{}",
    strict_mode: bool = False,
    *extraArg,
) -> Tuple[str, Any]:
    """循环输入，以某种格式
    notice: 输入时的提示
    fun: 格式函数
    err_note: 输入不符格式时的提示
    strict_mode: 是否将函数值作为结束循环的判断依据之一
    *extraArg: 对于函数的其他参数"""
    while True:
        result = ipt(notice)
        try:
            if strict_mode:
                if fun_result := fun(result, *extraArg):
                    break
            else:
                fun_result = fun(result, *extraArg)
                break
        except Exception as E:
            prt(err_note.format(E))
            continue
    return result, fun_result


def isin(sth: str, range_list: dict):
    sth = sth.lower()
    for bool_value, res_list in range_list.items():
        if sth in res_list:
            return bool_value
    raise ValueError


# 真假字符串判断
def bool_str(sth: str):
    try:
        return bool(float(sth))
    except:
        if str(sth).lower() in ("true", "真", "是", "y", "t"):
            return True
        elif str(sth).lower() in ("false", "假", "否", "f", "n"):
            return False
        else:
            raise ValueError


def float_str(sth: str):
    try:
        return float(sth)
    except ValueError:
        return float(
            sth.replace("壹", "1")
            .replace("贰", "2")
            .replace("叁", "3")
            .replace("肆", "4")
            .replace("伍", "5")
            .replace("陆", "6")
            .replace("柒", "7")
            .replace("捌", "8")
            .replace("玖", "9")
            .replace("零", "0")
            .replace("一", "1")
            .replace("二", "2")
            .replace("三", "3")
            .replace("四", "4")
            .replace("五", "5")
            .replace("六", "6")
            .replace("七", "7")
            .replace("八", "8")
            .replace("九", "9")
            .replace("〇", "0")
            .replace("洞", "0")
            .replace("幺", "1")
            .replace("俩", "2")
            .replace("两", "2")
            .replace("拐", "7")
            .replace("点", ".")
        )


def int_str(sth: str):
    return int(float_str(sth))
